package appClientModule;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Map;

import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;

/** 
 * Project Name:myapplet 
 * File Name:getCardInfoTest.java 
 * Package Name: 
 * Date:2017��8��23������9:41:35 
 * Copyright (c) 2017, liuhh@hengbao.com All Rights Reserved. 
 * 
*/

/** 
 * ClassName:getCardInfoTest <br/> 
 * Function: TODO ADD FUNCTION. <br/> 
 * Reason:   TODO ADD REASON. <br/> 
 * Date:     2017��8��23�� ����9:41:35 <br/> 
 * @author   liuhh 
 * @version   
 * @since    JDK 1.8 
 * @see       
 */
public class getCardInfoTest {
	@SuppressWarnings("unchecked")
	public static String getCardInfoTest(applet_pcsc ap) {
		try {
			final applet_pcsc app = ap;
			AccessController.doPrivileged(new PrivilegedExceptionAction() {
				public byte[] sendApdu(String apdu) {
					System.out.println(">>" + apdu);
					byte[] response = null;
					CardChannel comm = app.card.getBasicChannel();
					CommandAPDU getData = new CommandAPDU(app.hexStringToByteArray(apdu));
					try {
						ResponseAPDU resp = comm.transmit(getData);
						response = resp.getBytes();
						System.out.println("<<" + MsgGenUtil.buf2hex(response));
					} catch (CardException e) {
						e.printStackTrace();
						app.ApduRsp = ("Exception " + e.getMessage());
					}
					return response;
				}
				public byte[] byteConvert(byte[] src) {
			        byte []response = new byte[src.length];
			        for(int i=0;i<response.length;i++){
			        	response[i] = src[response.length-1-i];	
			        }
			        return response;
			    }
				public String f22ToImsi(String ret) {
					String MIN_A = ret.substring(2, 6); 
					String MIN_B = ret.substring(6,12);
					String CC = ret.substring(12,14);
					String DDDD = ret.substring(16,ret.length());
					StringBuffer sb = new StringBuffer();
					byte[] min_a = MsgGenUtil.BCD2Bytes(MIN_A);
					min_a = byteConvert(min_a);
					String min_value = ""+(MsgGenUtil.makeInt(min_a)+111);
					String min = rValue3(min_value);
					
					byte[] min_b = MsgGenUtil.BCD2Bytes(MIN_B);
					min_b = byteConvert(min_b);
					int d = MsgGenUtil.makeInt(min_b);
					String BBBBBB = Integer.toBinaryString(d);

					String ett = BBBBBB.substring(BBBBBB.length()-10,BBBBBB.length());//8~10
					min_value = ""+(Integer.valueOf(ett, 2)+111);
					ett = rValue3(min_value);
					
					String serven = BBBBBB.substring(BBBBBB.length()-10-4,BBBBBB.length()-10);//8~10
					serven = ""+(Integer.valueOf(serven, 2));
					serven = rValue1(serven);
					
					String four = BBBBBB.substring(0,BBBBBB.length()-10-4);//8~10
					four = ""+(Integer.valueOf(four, 2)+111);
					four = rValue3(four);
					
					byte[] min_c = MsgGenUtil.BCD2Bytes(CC);
					String mnc = ""+(min_c[0]+11);
					mnc = rValue2(mnc);
					
					byte[] min_d = MsgGenUtil.BCD2Bytes(DDDD);
					min_d = byteConvert(min_d);
					String mcc = ""+(MsgGenUtil.makeInt(min_d)+111);
					mcc = rValue3(mcc);
					
					sb.append(mcc);
					sb.append(mnc);
					sb.append(min);
					sb.append(four);
					sb.append(serven);
					sb.append(ett);

					System.out.println(sb.toString());
					return sb.toString();
				}
				public String rValue2(String v){
					String min_value = v;	
					int two = Integer.parseInt(min_value.substring(min_value.length()-1, min_value.length()));
					if(two == 0)
						min_value = ""+(Integer.parseInt(min_value)-10);
					
					int one = Integer.parseInt(min_value.substring(0, min_value.length()-1));
					if(one == 0 || one == 10)
						min_value = ""+(Integer.parseInt(min_value)-10*10);
					//System.out.println(min_value);
					for(int i=min_value.length();i<2;i++){
						min_value= "0"+min_value;
					}
					return min_value;
				}
				public String rValue3(String v){
					String min_value = v;
					
					int three = Integer.parseInt(min_value.substring(min_value.length()-1, min_value.length()));
					if(three == 0)
						min_value = ""+(Integer.parseInt(min_value)-10);
					
					int two = Integer.parseInt(min_value.substring(min_value.length()-2, min_value.length()-1));
					if(two == 0)
						min_value = ""+(Integer.parseInt(min_value)-10*10);
					int	one = Integer.parseInt(min_value.substring(0, min_value.length()-2));
					if(one == 0 || one == 10)
						min_value = ""+(Integer.parseInt(min_value)-10*100);
					for(int i=min_value.length();i<3;i++) {
						min_value = "0"+min_value;
					}
					return min_value;
				}
				public String rValue1(String v){
					String min_value = v;
					int one = Integer.parseInt(min_value.substring(0, min_value.length()));
					if(one >= 10)
						min_value = ""+(Integer.parseInt(min_value)%10);
					return min_value;
				}
				
				public String run() throws CardException {
					Map map = new HashMap();
					byte[] retmsg = null;
					String ret = "";
					// ��Ӧ���
					ret = app.Connect("*");
					if (ret != "") {
						map.put("resultCode", 1);
						map.put("CStatus", "0");
					} else {
						map.put("resultCode", 0);
						map.put("CStatus", "1");
					}
					String atr = app.GetATR();
					map.put("resultDesc", atr);
					// �жϰ�װcap���汾
					map.put("CAPVersion", "");
					// �жϿ��ڼ���״̬
					map.put("RStatus", "");
					// �жϿ�Ƭ������
					map.put("CardFirm", "");
					// �жϿ�Ƭʣ��ռ�
					map.put("Space", "");
					// ȡ��Ƭiccid
					String aid = "";
					
					retmsg = sendApdu("00a40004023f00");
					ret = MsgGenUtil.buf2hex(retmsg);
					
					retmsg = sendApdu("00a40004022fe2");
					ret = MsgGenUtil.buf2hex(retmsg);

					retmsg = sendApdu("00b000000a");
					ret = MsgGenUtil.buf2hex(retmsg);
					if (!ret.substring(ret.length() - 4, ret.length()).equals("9000")) {
						map.put("ICCID", "");
					} else {
						byte[] iccid = convertByHighToLow(retmsg,10);						
						map.put("ICCID", MsgGenUtil.buf2hex(iccid));
					}
					// ȡiccid����---------
					// ȡ4g aid-----------
					retmsg = sendApdu("00a40004022f00");
					ret = MsgGenUtil.buf2hex(retmsg);

					if (retmsg[3] == 0x05) {
						byte[] record = new byte[1];
						record[0] = retmsg[8];
						int index = Integer.parseInt(MsgGenUtil.buf2hex(record), 10);
						byte[] length = new byte[2];
						System.arraycopy(retmsg, 6, length, 0, 2);
						int len = Integer.parseInt(MsgGenUtil.buf2hex(length), 10);

						for (int i = 1; i <= index; i++) {
							retmsg = sendApdu("00b2" + MsgGenUtil.buf2hex(MsgGenUtil.Int2Bytes1(i)) + "04" + len);
							ret = MsgGenUtil.buf2hex(retmsg);
							byte[] length2 = new byte[1];
							length2[0] = retmsg[3];
							int len2 = Integer.parseInt(MsgGenUtil.buf2hex(length2), 16);
							if (ret.contains("871002")) {
								aid = ret.substring(8, len2 * 2 + 8);
								break;
							}
						}
					}
					// ��ȡ4g aid����-----

					// ȡgsm imsi
					retmsg = sendApdu("00a40004027f20");
					ret = MsgGenUtil.buf2hex(retmsg);

					retmsg = sendApdu("00a40004026f07");
					ret = MsgGenUtil.buf2hex(retmsg);

					retmsg = sendApdu("00b0000009");
					ret = MsgGenUtil.buf2hex(retmsg);
					if (!ret.substring(ret.length() - 4, ret.length()).equals("9000")) {
						map.put("G-IMSI", "");
					} else {
//						byte[] gsmimsi = new byte[8];
						int l = retmsg[1]>>4&0x0f;
//						gsmimsi[0] = (byte)(l);
						byte[] data = new byte[7];
						System.arraycopy(retmsg, 2, data, 0, data.length);
						byte[] imsi = convertByHighToLow(data, data.length);
//						System.arraycopy(imsi, 0, gsmimsi, 1, imsi.length);
						System.out.println(l+MsgGenUtil.buf2hex(imsi));
						map.put("G-IMSI", l+""+MsgGenUtil.buf2hex(imsi));
					}
					// ----------- 2g imsi---����
					// ȡcdma imsi
					retmsg = sendApdu("00a40004027f25");
					ret = MsgGenUtil.buf2hex(retmsg);
					retmsg = sendApdu("00a40004026f22");
					ret = MsgGenUtil.buf2hex(retmsg);
					retmsg = sendApdu("00b000000a");
					ret = MsgGenUtil.buf2hex(retmsg);
					if (!ret.substring(ret.length() - 4, ret.length()).equals("9000")) {
						map.put("C-IMSI", "");
					} else {
						//ת��imsi
						String cdma = f22ToImsi(ret.substring(0, ret.length() - 4));
						map.put("C-IMSI", cdma);
					}
					// ----------- cdma imsi---����
					// ȡlte imsi
					retmsg = sendApdu("00a4040410" + aid);
					ret = MsgGenUtil.buf2hex(retmsg);

					retmsg = sendApdu("00a40004026f07");
					ret = MsgGenUtil.buf2hex(retmsg);

					retmsg = sendApdu("00b0000009");
					ret = MsgGenUtil.buf2hex(retmsg);
					if (!ret.substring(ret.length() - 4, ret.length()).equals("9000")) {
						map.put("L-IMSI", "");
					} else {
//						map.put("lte", ret.substring(2, ret.length() - 4));
//						System.out.println(ret.substring(2, ret.length() - 4));
//						byte[] lteimsi = new byte[8];
//						int l = retmsg[0]>>4&0x0f;
						int l = retmsg[1] >> 4 & 0x0f;
//						lteimsi[0] = (byte)(l);
						byte[] data = new byte[7];
						System.arraycopy(retmsg, 2, data, 0, data.length);
						byte[] imsi = convertByHighToLow(data, data.length);
//						System.arraycopy(imsi, 0, lteimsi, 1, imsi.length);
						System.out.println(l+MsgGenUtil.buf2hex(imsi));
						map.put("L-IMSI", l+MsgGenUtil.buf2hex(imsi));
					}
					// ----------- lte imsi---����
					// �ж��ǲ���ΪNFC��Ƭ
//					ret = app.cardReset();
//					if (ret != "") {
//						return "��λʧ��";
//					}
//					retmsg = sendApdu("00a40004023f00");
//					ret = MsgGenUtil.buf2hex(retmsg);
					
					retmsg = sendApdu("00a4040407A0000001510000");
					ret = MsgGenUtil.buf2hex(retmsg);
					if (ret.substring(ret.length() - 4, ret.length()).equals("9000")) {
						map.put("CardType", "1");
					} else {
						map.put("CardType", "2");
					}

					app.Disconnect(true);
					
					ObjectMapper mapper = new ObjectMapper();
					String json = "";
					try {
						json = mapper.writeValueAsString(map);
					} catch (JsonProcessingException e) {
						e.printStackTrace();
					} //������ת����json  
				      
					app.ApduRsp = json;
					return app.ApduRsp;
				}
				private byte[] convertByHighToLow(byte[] retmsg, int length) {
					byte[] data = new byte[length];
					for(int i=0;i<data.length;i++){
						byte a = retmsg[i];
						int b1=a<<4&0xf0; 
						int b2=a>>4&0x0f;
						data[i] = (byte) (b1+b2);
					}
					System.out.println(MsgGenUtil.buf2hex(data));
					return data;
				}
			});
		} catch (PrivilegedActionException e) {
			e.printStackTrace();
		}
		return ap.ApduRsp;
	}
}
  